package org.opencv.test1;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PreviewCallback;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class testOpenCVActivity extends Activity implements SurfaceHolder.Callback {

	Camera camera;
	SurfaceView surfaceView;
	SurfaceHolder surfaceHolder;
	boolean previewing = false;
	LayoutInflater controlInflater = null;
	boolean isEnabled = false;
	boolean isRemote = false;
	
	private Button processButton;
	private Button sendButton;
	private Button disableButton;

	private static final String IMAGE_DIRECTORY = "/sdcard/DCIM/Camera";
	private static final int ACTIVITY_SELECT_CAMERA = 0;
	private static final int ACTIVITY_SELECT_IMAGE = 1;
	private static final String TAG = "MAIN_ACTIVITY";
	private static final int CAMERA_ID = Menu.FIRST;
	private static final int SEND_ID = Menu.FIRST + 1;
	private String mCurrentImagePath = null;
	private OpenCV opencv = new OpenCV();
	private ImageView mImageView;
	Bitmap currentProcessedImage;
	//boolean isRemote = false;
	// camera capture id
	private static final int CAMERA_PIC_REQUEST = 1337;

	// preview
	private Preview mPreview;
	Camera mCamera;

	//Threads
	Upload upThread;
	Thread thread;



	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		setOrientation();
		disableScreenTurnOff();
		
		processButton = (Button)findViewById(R.id.buttonProcess);
		sendButton = (Button)findViewById(R.id.buttonSend);
		disableButton = (Button)findViewById(R.id.buttonDisable);
		processButton.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View arg0) {
				enable();
				setRemote(false);
				
			}});
		sendButton.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View arg0) {
				enable();
				setRemote(true);
				
			}});
		disableButton.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View arg0) {
				disable();
				
			}});
			 

		getWindow().setFormat(PixelFormat.UNKNOWN);
		surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
		surfaceHolder = surfaceView.getHolder();
		surfaceHolder.addCallback(this);
		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

		mImageView = new ImageView(this);
		((FrameLayout) findViewById(R.id.processed)).addView(mImageView);

		/*
		// Hide the window title.
		//requestWindowFeature(Window.FEATURE_NO_TITLE);
		//getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

		// Create a RelativeLayout container that will hold a SurfaceView,
		// and set it as the content of our activity.
		mPreview = new Preview(this);
		((FrameLayout) findViewById(R.id.preview)).addView(mPreview);

		mImageView = new ImageView(this);
		((FrameLayout) findViewById(R.id.processed)).addView(mImageView);

		//setContentView(mPreview);
		 */

		//mImageView = new ImageView(this);
		//setContentView(mImageView);
		//Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 

		//startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST); 

	}

	/**
	 * Set's the orientation to landscape
	 */
	public void setOrientation() {
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
	}

	/**
	 * Avoid that the screen get's turned off by the system.
	 */
	public void disableScreenTurnOff() {
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
				WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
	}


	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(0, CAMERA_ID, 0, "Process");
		menu.add(0, SEND_ID, 0, "Send");
		return true;
	}
	
	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		enable();

		switch (item.getItemId()) {
		case CAMERA_ID:
			setRemote(false);
			return true;
		case SEND_ID:
			setRemote(true);
			return true;
			/*
			isRemote = true;
			Upload upThread = new Upload(currentProcessedImage);
			return true;
			 */
		}

		return super.onMenuItemSelected(featureId, item);
	}


	public void setImage(Bitmap bm){
		mImageView.setImageBitmap(bm);
	}

	public void enable(){
		isEnabled = true;
	}
	public void disable(){
		isEnabled = false;
	}
	public void setRemote(boolean x){
		isRemote = x;
	}

	

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
		if(previewing){
			camera.stopPreview();
			previewing = false;
		}

		if (camera != null){
			try {
				camera.setPreviewDisplay(surfaceHolder);
				camera.startPreview();
				previewing = true;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		camera = Camera.open();

		try {

			camera.setPreviewDisplay(holder);
			Parameters param = camera.getParameters();
			param.setPreviewFrameRate(1);
			param.setColorEffect(Camera.Parameters.EFFECT_MONO);
			camera.setParameters(param);

			camera.setPreviewCallback(new PreviewCallback() {

				public void onPreviewFrame(byte[] data, Camera arg1) {
					
					try{
						/*
						String filename="/sdcard/223.jpg"; 
						FileOutputStream out;
						out = new FileOutputStream(filename);
						bmp.compress(Bitmap.CompressFormat.JPEG, 90, out);
						out.flush();
						out.close();
						out=null;
*/
						if(!isEnabled)
							return;
						
						int width = arg1.getParameters().getPictureSize().width;
						int height = arg1.getParameters().getPictureSize().height;
						int[] rgb = Utility.decodeYUV420SP(data, width, height);
						Bitmap bmp = Bitmap.createBitmap(rgb, width, height,Bitmap.Config.ARGB_8888);
						
						
						if(isRemote){
							// here u wanna send the image to socket...
							Socket socket = new Socket("128.189.245.116",12345);
							OutputStream os = socket.getOutputStream();
							bmp.compress(CompressFormat.PNG, 0, os);
							os.flush();
							os.close();

							// receive images from the serverr
							int totalRead = 0;
							byte[] oldFile = null;
							byte[] newFile = null;

							try{
								ServerSocket ss = new ServerSocket(12345);
								Socket s = ss.accept();
								InputStream is = s.getInputStream();

								int offset = 0;

								byte[] b = new byte[8192];
								int read;
								while ((read=is.read(b)) !=-1) {
									totalRead+=read;
									if(offset == 0){
										newFile = new byte[read];
										System.arraycopy(b, 0, newFile, 0, read);
									}
									else{
										oldFile = newFile;
										newFile = new byte[totalRead];
										System.arraycopy(oldFile,0,newFile,0,offset);
										System.arraycopy(b, 0, newFile, offset, read);
									}

									offset += read;	
								}

							}catch (Exception e) {

							}

							BitmapFactory.Options opts = new BitmapFactory.Options();
							Bitmap bm;
							bm = BitmapFactory.decodeByteArray(newFile, 0, newFile.length);
							
							setImage(bm);
							// finish receiving images from the server
						}
						else
						{

							int[] pixels = new int[width * height];
							bmp.getPixels(pixels, 0, width, 0, 0, width, height);
							opencv.setSourceImage(pixels, width, height);
							long start = System.currentTimeMillis();
							opencv.extractSURFFeature();
							long end = System.currentTimeMillis();
							byte[] imageData = opencv.getSourceImage();
							long elapse = end - start;

							bmp = BitmapFactory.decodeByteArray(imageData, 0,
									imageData.length);
							setImage(bmp);

						}

					}catch(Exception e){};

				}
			});
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		camera.stopPreview();
		camera.release();
		camera = null;
		previewing = false;
	}


}